﻿using System;
using System.Runtime.InteropServices;

namespace UacHelper
{
    internal class NativeMethods
    {
        public const uint STANDARD_RIGHTS_REQUIRED = 983040u;

        public const uint STANDARD_RIGHTS_READ = 131072u;

        public const uint TOKEN_ASSIGN_PRIMARY = 1u;

        public const uint TOKEN_DUPLICATE = 2u;

        public const uint TOKEN_IMPERSONATE = 4u;

        public const uint TOKEN_QUERY = 8u;

        public const uint TOKEN_QUERY_SOURCE = 16u;

        public const uint TOKEN_ADJUST_PRIVILEGES = 32u;

        public const uint TOKEN_ADJUST_GROUPS = 64u;

        public const uint TOKEN_ADJUST_DEFAULT = 128u;

        public const uint TOKEN_ADJUST_SESSIONID = 256u;

        public const uint TOKEN_READ = 131080u;

        public const uint TOKEN_ALL_ACCESS = 983551u;

        public const int ERROR_INSUFFICIENT_BUFFER = 122;

        public const int SECURITY_MANDATORY_UNTRUSTED_RID = 0;

        public const int SECURITY_MANDATORY_LOW_RID = 4096;

        public const int SECURITY_MANDATORY_MEDIUM_RID = 8192;

        public const int SECURITY_MANDATORY_HIGH_RID = 12288;

        public const int SECURITY_MANDATORY_SYSTEM_RID = 16384;

        /// <summary>
        /// Sets the elevation required state for a specified button or command 
        /// link to display an elevated icon. 
        /// </summary>
        /// <remarks></remarks>
        public const uint BCM_SETSHIELD = 5644u;

        /// <summary>
        /// The function opens the access token associated with a process.
        /// </summary>
        /// <param name="hProcess">
        /// A handle to the process whose access token is opened.
        /// </param>
        /// <param name="desiredAccess">
        /// Specifies an access mask that specifies the requested types of access 
        /// to the access token. 
        /// </param>
        /// <param name="hToken">
        /// Outputs a handle that identifies the newly opened access token 
        /// when the function returns.
        /// </param>
        /// <returns></returns>
        [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool OpenProcessToken(IntPtr hProcess, uint desiredAccess, out SafeTokenHandle hToken);

        /// <summary>
        /// The function creates a new access token that duplicates one already
        /// in existence.
        /// </summary>
        /// <param name="ExistingTokenHandle">
        /// A handle to an access token opened with TOKEN_DUPLICATE access.
        /// </param>
        /// <param name="ImpersonationLevel">
        /// Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that 
        /// supplies the impersonation level of the new token.
        /// </param>
        /// <param name="DuplicateTokenHandle">
        /// Outputs a handle to the duplicate token. 
        /// </param>
        /// <returns></returns>
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool DuplicateToken(SafeTokenHandle ExistingTokenHandle, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, out SafeTokenHandle DuplicateTokenHandle);

        /// <summary>
        /// The function retrieves a specified type of information about an 
        /// access token. The calling process must have appropriate access rights
        /// to obtain the information.
        /// </summary>
        /// <param name="hToken">
        /// A handle to an access token from which information is retrieved.
        /// </param>
        /// <param name="tokenInfoClass">
        /// Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to 
        /// identify the type of information the function retrieves.
        /// </param>
        /// <param name="pTokenInfo">
        /// A pointer to a buffer the function fills with the requested 
        /// information.
        /// </param>
        /// <param name="tokenInfoLength">
        /// Specifies the size, in bytes, of the buffer pointed to by the 
        /// TokenInformation parameter. 
        /// </param>
        /// <param name="returnLength">
        /// A pointer to a variable that receives the number of bytes needed for 
        /// the buffer pointed to by the TokenInformation parameter. 
        /// </param>
        /// <returns></returns>
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetTokenInformation(SafeTokenHandle hToken, TOKEN_INFORMATION_CLASS tokenInfoClass, IntPtr pTokenInfo, int tokenInfoLength, out int returnLength);

        /// <summary>
        /// Sends the specified message to a window or windows. The function 
        /// calls the window procedure for the specified window and does not 
        /// return until the window procedure has processed the message. 
        /// </summary>
        /// <param name="hWnd">
        /// Handle to the window whose window procedure will receive the message.
        /// </param>
        /// <param name="Msg">Specifies the message to be sent.</param>
        /// <param name="wParam">
        /// Specifies additional message-specific information.
        /// </param>
        /// <param name="lParam">
        /// Specifies additional message-specific information.
        /// </param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);

        /// <summary>
        /// The function returns a pointer to a specified subauthority in a 
        /// security identifier (SID). The subauthority value is a relative 
        /// identifier (RID).
        /// </summary>
        /// <param name="pSid">
        /// A pointer to the SID structure from which a pointer to a subauthority
        /// is to be returned.
        /// </param>
        /// <param name="nSubAuthority">
        /// Specifies an index value identifying the subauthority array element 
        /// whose address the function will return.
        /// </param>
        /// <returns>
        /// If the function succeeds, the return value is a pointer to the 
        /// specified SID subauthority. To get extended error information, call
        /// GetLastError. If the function fails, the return value is undefined.
        /// The function fails if the specified SID structure is not valid or if 
        /// the index value specified by the nSubAuthority parameter is out of
        /// bounds. 
        /// </returns>
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr GetSidSubAuthority(IntPtr pSid, uint nSubAuthority);
    }
}
